<template>
  <div class="editor-container">
    <a-layout class="editor-main">
      <a-layout-sider width="250" class="widget-config-sidebar">
        <div class="components-list">
          <template v-if="basicFields.length">
            <div class="widget-cate">基础字段</div>
            <draggable tag="ul" :list="basicComponents"
                       v-bind="{group:{ name:'people', pull:'clone',put:false},sort:false, ghostClass: 'ghost'}"
                       @end="handleMoveEnd"
                       @start="handleMoveStart"
                       :move="handleMove"
            >

              <li v-if="basicFields.indexOf(item.type)>=0" class="form-edit-widget-label"
                  :class="{'no-put': item.type === 'divider'}" v-for="(item, index) in basicComponents" :key="index">
                <a>
                  <i class="icon iconfont" :class="item.icon"></i>
                  <span>{{item.name}}</span>
                </a>
              </li>
            </draggable>
          </template>

          <template v-if="advanceFields.length">
            <div class="widget-cate">高级字段</div>
            <draggable tag="ul" :list="advanceComponents"
                       v-bind="{group:{ name:'people', pull:'clone',put:false},sort:false, ghostClass: 'ghost'}"
                       @end="handleMoveEnd"
                       @start="handleMoveStart"
                       :move="handleMove"
            >

              <li v-if="advanceFields.indexOf(item.type) >= 0" class="form-edit-widget-label"
                  :class="{'no-put': item.type === 'table'}" v-for="(item, index) in advanceComponents" :key="index">
                <a>
                  <i class="icon iconfont" :class="item.icon"></i>
                  <span>{{item.name}}</span>
                </a>
              </li>
            </draggable>
          </template>

          <template v-if="layoutFields.length">
            <div class="widget-cate">布局字段</div>
            <draggable tag="ul" :list="layoutComponents"
                       v-bind="{group:{ name:'people', pull:'clone',put:false},sort:false, ghostClass: 'ghost'}"
                       @end="handleMoveEnd"
                       @start="handleMoveStart"
                       :move="handleMove"
            >

              <li v-if="layoutFields.indexOf(item.type) >=0" class="form-edit-widget-label no-put"
                  v-for="(item, index) in layoutComponents" :key="index">
                <a>
                  <i class="icon iconfont" :class="item.icon"></i>
                  <span>{{item.name}}</span>
                </a>
              </li>
            </draggable>
          </template>

        </div>
      </a-layout-sider>

      <a-layout class="center-container">
        <div class="btn-bar">
          <a-button type="link" size="large" @click="handleUpload"><a-icon type="cloud" />导入JSON</a-button>
          <a-button type="link" size="large" @click="handleClear"><a-icon type="delete" />清空</a-button>
          <a-button type="link" size="large" @click="handlePreview"><a-icon type="eye" />预览</a-button>
          <a-button type="link" size="large" @click="handleGenerateJson"><a-icon type="snippets" />生成JSON</a-button>
          <a-button type="link" size="large" @click="handleGenerateCode"><a-icon type="code" /> 生成代码</a-button>
        </div>
        <a-layout-content class="main-container" :class="{'widget-empty': widgetForm.list.length === 0}">
          <widget-form v-if="!resetJson"  ref="widgetForm" :data="widgetForm" :select.sync="widgetFormSelect"></widget-form>
        </a-layout-content>
      </a-layout>

      <a-layout-sider width="250" class="widget-config-container">
        <a-tabs defaultActiveKey="1" size="large" class="right-tabs">
          <a-tab-pane tab="字段属性" key="1" style="padding:10px">
            <widget-config :data="widgetFormSelect"></widget-config>
          </a-tab-pane>
          <a-tab-pane tab="表单属性" key="2" style="padding:10px">
            <form-config :data="widgetForm.config"></form-config>
          </a-tab-pane>
        </a-tabs>
      </a-layout-sider>
    </a-layout>
  </div>
</template>

<script>
  import Draggable from 'vuedraggable'
  import WidgetConfig from '@/components/WidgetConfig'
  import FormConfig from '@/components/FormConfig'
  import WidgetForm from '@/components/WidgetForm'
  import CusDialog from '@/components/CusDialog'
  // import GenerateForm from '@/components/GenerateForm'
  import Clipboard from 'clipboard'
  import {
    basicComponents,
    layoutComponents,
    advanceComponents,
    componentFieldsName
  } from '@/components/componentsConfig.js'
  import request from '../util/request.js'
  import generateCode from '@/components/generateCode.js'

  export default {
    name: 'gj-editor',
    components: {
      Draggable,
      WidgetConfig,
      FormConfig,
      WidgetForm,
      CusDialog,
      // GenerateForm
    },
    props: {
      preview: {
        type: Boolean,
        default: false
      },
      generateCode: {
        type: Boolean,
        default: false
      },
      generateJson: {
        type: Boolean,
        default: false
      },
      upload: {
        type: Boolean,
        default: false
      },
      clearable: {
        type: Boolean,
        default: false
      },
      basicFields: {
        type: Array,
        default: () => ['input', 'textarea', 'number', 'radio', 'checkbox', 'time', 'date', 'rate', 'color', 'select', 'switch', 'slider', 'text']
      },
      advanceFields: {
        type: Array,
        default: () => ['blank', 'imgupload', 'editor', 'cascader']
      },
      layoutFields: {
        type: Array,
        default: () => ['grid']
      }
    },
    data() {
      return {
        basicComponents,
        layoutComponents,
        advanceComponents,
        resetJson: false,
        widgetForm: {
          list: [],
          config: {
            labelWidth: 100,
            labelPosition: 'horizontal',
            size: 'default',
            name: '',
            formKey: ''
          }
        },
        configTab: 'widget',
        widgetFormSelect: null,
        previewVisible: false,
        jsonVisible: false,
        codeVisible: false,
        uploadVisible: false,
        remoteFuncs: {
          func_test(resolve) {
            setTimeout(() => {
              const options = [
                {id: '1', name: '1111'},
                {id: '2', name: '2222'},
                {id: '3', name: '3333'}
              ]

              resolve(options)
            }, 2000)
          },
          funcGetToken(resolve) {
            request.get('http://tools-server.xiaoyaoji.cn/api/uptoken').then(res => {
              resolve(res.uptoken)
            })
          },
          upload_callback(response, file, fileList) {
            console.log('callback', response, file, fileList)
          }
        },
        widgetModels: {},
        blank: '',
        htmlTemplate: '',
        vueTemplate: '',
        jsonTemplate: '',
        uploadEditor: null,
        jsonCopyValue: '',
        jsonClipboard: null,
        jsonEg: `{
          "list": [],
          "config": {
            "labelWidth": 100,
            "labelPosition": "top",
            "size": "small"
          }
        }`,
        codeActiveName: 'vue'
      }
    },
    mounted() {
      this._loadComponents()
    },
    methods: {
      _loadComponents() {
        this.basicComponents = this.basicComponents.map(item => {
          return {
            ...item,
            name: componentFieldsName[item.type]
          }
        })
        this.advanceComponents = this.advanceComponents.map(item => {
          return {
            ...item,
            name: componentFieldsName[item.type]
          }
        })
        this.layoutComponents = this.layoutComponents.map(item => {
          return {
            ...item,
            name: componentFieldsName[item.type]
          }
        })
      },
      handleConfigSelect(value) {
        this.configTab = value
      },
      handleMoveEnd(evt) {
        console.log('end', evt)
      },
      handleMoveStart({oldIndex}) {
        console.log('start', oldIndex, this.basicComponents)
      },
      handleMove() {
        return true
      },
      handlePreview() {
        console.log(this.widgetForm)
        this.previewVisible = true
      },
      handleTest() {
        this.$refs.generateForm.getData().then(data => {
          this.$alert(data, '').catch(e => {
          })
          this.$refs.widgetPreview.end()
        }).catch(e => {
          this.$refs.widgetPreview.end()
        })
      },
      handleReset() {
        this.$refs.generateForm.reset()
      },
      handleGenerateJson() {
        this.jsonVisible = true
        this.jsonTemplate = this.widgetForm
        console.log(JSON.stringify(this.widgetForm))
        this.$nextTick(() => {
          const editor = ace.edit('jsoneditor')
          editor.session.setMode('ace/mode/json')

          if (!this.jsonClipboard) {
            this.jsonClipboard = new Clipboard('.json-btn')
            this.jsonClipboard.on('success', (e) => {
              this.$message.success('复制成功')
            })
          }
          this.jsonCopyValue = JSON.stringify(this.widgetForm)
        })
      },
      handleGenerateCode() {
        this.codeVisible = true
        this.htmlTemplate = generateCode(JSON.stringify(this.widgetForm), 'html')
        this.vueTemplate = generateCode(JSON.stringify(this.widgetForm), 'vue')
        this.$nextTick(() => {
          const editor = ace.edit('codeeditor')
          editor.session.setMode('ace/mode/html')

          const vueEditor = ace.edit('vuecodeeditor')
          vueEditor.session.setMode('ace/mode/html')
        })
      },
      handleUpload() {
        this.uploadVisible = true
        this.$nextTick(() => {
          this.uploadEditor = ace.edit('uploadeditor')
          this.uploadEditor.session.setMode('ace/mode/json')
        })
      },
      handleUploadJson() {
        try {
          this.setJSON(JSON.parse(this.uploadEditor.getValue()))
          this.uploadVisible = false
        } catch (e) {
          this.$message.error(e.message)
          this.$refs.uploadJson.end()
        }
      },
      handleClear() {
        this.widgetForm = {
          list: [],
          config: {
            labelWidth: 100,
            labelPosition: 'right',
            size: 'small',
            customClass: ''
          }
        }

        this.widgetFormSelect = {}
      },
      getJSON() {
        return this.widgetForm
      },
      getHtml() {
        return generateCode(JSON.stringify(this.widgetForm))
      },
      setJSON(json) {
        this.widgetForm = json

        if (json.list.length > 0) {
          this.widgetFormSelect = json.list[0]
        }
      },
      handleInput(val) {
        console.log(val)
        this.blank = val
      },
      handleDataChange(field, value, data) {
        console.log(field, value, data)
      }
    },
    watch: {
      widgetForm: {
        deep: true,
        handler: function (val) {
          console.log(this.$refs.widgetForm)
        }
      },
      $lang: function (val) {
        this._loadComponents()
      }
    }
  }
</script>
